package features.advance.leetcode.interview.alibaba;

import java.io.InputStream;
import java.util.*;

/**
 *
 * @author LIN
 * @date 2021-08-16
 */
public class MainB {

    public static void main(String[] args) {
        Solution solution = new Solution();
        // 关键字可能会有包含的情况，像是工作和工作性质这种
        List<String> keywords = Arrays.asList("天气","工作","论语","天空","论断","工程师","工作性质");
        System.out.println(solution.parse(keywords));
        String text = "的框架阿来得及发天气量较大空间按付款金工作性质额放假啊看似简单发卡机扣水电费论语的金发科技砥砺奋进ad开始了放假啊djksj佳都科技诶f  工作  健康的骄傲来得及是否ad啊放假啊天气肯德基ask剪短发卡机的开始放假阿卡第三方开决胜巅峰科技阿克苏打飞机卡迪夫健身卡京东方天气的框架阿来得及发天气量较大空间按付款金工作性质额放假啊看似简单发卡机扣水电费论语的金发科技砥砺奋进ad开始了放假啊djksj佳都科技诶f  工作  健康的骄傲来得及是否ad啊放假啊天气肯德基ask剪短发卡机的开始放假阿卡第三方开决胜巅峰科技阿克苏打飞机卡迪夫健身卡京东方天气的框架阿来得及发天气量较大空间按付款金工作性质额放假啊看似简单发卡机扣水电费论语的金发科技砥砺奋进ad开始了放假啊djksj佳都科技诶f  工作  健康的骄傲来得及是否ad啊放假啊天气肯德基ask剪短发卡机的开始放假阿卡第三方开决胜巅峰科技阿克苏打飞机卡迪夫健身卡京东方天气";
        text+=text;
        text+=text;
        text+=text;
        text+=text;
        text+=text;
        Map<String, List<Integer>> stringListMap = solution.searchKeywordInText(text, keywords);
        System.out.println(stringListMap);


    }

    /**
     * B
     * 1、文本匹配接口:
     * 现有一万个中文关键词(长度2-20不等):
     * 关键词
     * 天气
     * 工作
     * 论语
     *
     *
     * 现在要实现一个方法,输入一个文本,可以快速查找出文本中所有出现的中文关键词内容及其在原始文本中的位置,
     * 要求时间和空间复杂度都尽可能低,不允许超过o(n^2)
     * publicMap<String,List(Integer> searchKeywordlnText(String text, List<String> keywords) {//text是原始文本,
     * keywords是关键字列表,输出结果key是关键字, value是命中的关键字在原始文本中的位置
     */
    static class Solution {
        public Map<String, List<Integer>> searchKeywordInText(String text,List<String> keywords){
            // 先将关键字，解析程类似树形的，索引结构
            // 然后逐个匹配单个字节，连续匹配到了某个关键字，就存到结果map里
            Map<Object, Object> parse = parse(keywords);
            Map<String, List<Integer>> res = new LinkedHashMap<>(16);
            char[] array = text.toCharArray();
            Map<Object, Object> tmp = parse;
            int location = array.length;
            for (int i = 0; i < array.length; i++) {
                char c = array[i];
                if(tmp.containsKey(c)){
                    tmp = (Map<Object, Object>) tmp.get(c);
                    location = Math.min(location,i);
                    // 关键字的全称，存在层级结构的最后一级，对应的key是keyword，可以通过这个
                    // ，方便快速取出匹配到的关键字
                    if(tmp.containsKey("keyword")){
                        String k = tmp.get("keyword").toString();
                        if(!res.containsKey(k)){
                            res.put(k,new LinkedList<>());
                        }
                        res.get(k).add(location);
                        location = array.length;
                        if(tmp.size()>1){

                        }else{
                            tmp = parse;
                        }
                    }
                }else{
                    tmp = parse;
                }

            }
            return res;
        }
        public Map<Object,Object> parse(List<String> keywords){

            Map<Object,Object> map = new LinkedHashMap<>(16);
            Map<Object,Object> tmp = map;

            for (int i = 0; i < keywords.size(); i++) {
                String str = keywords.get(i);
                char[] chars = str.toCharArray();
                for (int j = 0; j < chars.length; j++) {
                    char s = chars[j];
                    if(tmp.containsKey(s)){
                        Object o = tmp.get(s);
                        if(o.getClass().equals(String.class)){
                            // 数据复杂后，可能出现字符串或者其他类型
                        }else if(o.getClass().equals(LinkedHashMap.class)){
                            tmp = (LinkedHashMap<Object,Object>)o;
                        }
                    }else {
                        Map<Object, Object> map1 = new LinkedHashMap<>(16);
                        tmp.put(s,map1);
                        tmp = map1;
                    }
                    if(j == chars.length - 1){
                        tmp.put("keyword",str);
                    }
                }
                tmp = map;
            }
            return map;
        }


        /**
         * 7、地理位置对应IP地址存储结构设计:
         * 现在有200万条IPV4地址和其对应的地理位置信息数据,
         * 请设计一种内存数据结构、初始化函数和查询函数
         * 要求:
         * 高性能、支持多线程查询、内存占用尽可能少
         * 数据源:
         * 33.98.125.7,中国,浙江,杭州,西湖区33.78.15.22,中国,浙江,杭州,演江区
         * 输入: 33.98.125.7
         * 输出:{"country": "中国","province":"浙江","city":"杭州","county":"西湖区" }
         */

        /**
         * 初始化接口：
         * 输入内容为多行记录，记录格式如数据源示例
         * @param inputData
         */
        public void init(InputStream inputData){
            // 将数据源都解析成层级结构，还得维护个码值和中文地址的映射关系
            /*
                {
                "32": {},
                "33": {
                    "98": {},
                    "name": "中国"
                    }
                }
             */
            //就像这种结构

        }

        /**
         * 查询接口
         * 查询一个IP地址对应的地理位置信息
         * 返回值的类型可以自己定义
         * @return
         */
        public Object search(String ip){
            // 查询的时候，就先根据.号分割ip，深入到map每层去获取ip片段对应的中文名，类似树形查找，查找速度很快

            return null;
        }
    }
}
